using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Configuration;
using Microsoft.Extensions.Options;
using System;

namespace Micro.Extensions.Log
{
    /// <summary>
    /// https://www.codeproject.com/Articles/1556475/How-to-Write-a-Custom-Logging-Provider-in-ASP-NET
    /// </summary>
    public static class LogExtensions
    {
        /// <summary>
        /// Adds a console logger named 'Console' to the factory.
        /// </summary>
        /// <param name="builder">The <see cref="ILoggingBuilder"/> to use.</param>
        /// <param name="configuration"></param>
        public static ILoggingBuilder AddMicroLogger(this ILoggingBuilder builder, IConfiguration configuration)
        {
            builder.AddConfiguration();
            builder.Services.Configure<MicroLoggerOptions>(configuration.GetSection("MicroLog"));
            return builder.AddMicroLogger();
        }

        /// <summary>
        /// Adds a console logger named 'Console' to the factory.
        /// </summary>
        /// <param name="builder">The <see cref="ILoggingBuilder"/> to use.</param>
        /// <param name="configure"></param>
        public static ILoggingBuilder AddMicroLogger(this ILoggingBuilder builder, Action<MicroLoggerOptions> configure)
        {
            if (configure == null)
            {
                throw new ArgumentNullException(nameof(configure));
            }

            builder.AddConfiguration();
            builder.Services.Configure(configure);
            builder.AddMicroLogger();
            return builder;
        }

        /// <summary>
        /// Adds a console logger named 'Console' to the factory.
        /// </summary>
        /// <param name="builder">The <see cref="ILoggingBuilder"/> to use.</param>
        private static ILoggingBuilder AddMicroLogger(this ILoggingBuilder builder)
        {
            builder.Services.TryAddSingleton<ILoggerWriter, ConsoleLogWriter>();
            builder.Services.TryAddSingleton<IFileDiskWriter, FileDiskWriter>();
            builder.Services.TryAddSingleton<ILoggerProvider, MicroLoggerProvider>();
            builder.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();



            builder.Services.TryAddSingleton<IConfigureOptions<MicroLoggerOptions>, MicroLoggerOptionsSetup>();
            builder.Services.TryAddSingleton<IOptionsChangeTokenSource<MicroLoggerOptions>, LoggerProviderOptionsChangeTokenSource<MicroLoggerOptions, MicroLoggerProvider>>();

            return builder;
        }
    }
}
